home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / MATH / PASCMP / PASCMPLX.PAS < prev    next >
Pascal/Delphi Source File  |  1994-06-29  |  8KB  |  227 lines

  1. { Complex mathematics unit for Borland Pascal                                 }
  2. { (c)1994 by Alex Klimovitski                                                 }
  3.  
  4. { *PasCmplx works with coprocessors 80287 and higher.                         }
  5. { *PasCmplx determines the presence of 80387 and uses its fast instructions.  }
  6. { *See PASCMPLX.ASM for details how to change the unit for using with 8087.   }
  7. { *Call CInit BEFORE using any routines from this unit except CCeck87.        }
  8. { *If CInit returns non-zero, don't call any other routines except CCeck87.   }
  9. { *You can directly assign complex variables, for example:                    }
  10. {                                                                             }
  11. {    var Z, P: Complex;                                                       }
  12. {       Z := Cmplx(3.0, -2.0);                                                }
  13. {       P := Z;                                                               }
  14. {                                                                             }
  15. { *Don't use real constants and variables for complex operations, for example:}
  16. {                                                                             }
  17. {    var Z, P: Complex;                                                       }
  18. {    WRONG1: P := Z + 5.0;                                                    }
  19. {    WRONG2: P := CAdd(Z, 5.0);                                               }
  20. {    CORRECT: P := CAdd(Z, Cmplx(5.0, 0));                                    }
  21. {                                                                             }
  22. {    As 1 and i (or j) for complex operations use also C1 and Ci (or Cj):     }
  23. {                                                                             }
  24. {    WRONG: Z := CAdd(Z, 1);                                                  }
  25. {    CORRECT: Z := CAdd(Z, C1);                                               }
  26. {                                                                             }
  27. {    However, you can use real 0 for complex operations:                      }
  28. {                                                                             }
  29. {    CORRECT: P := CPow(Z, 0.0)                                               }
  30. {                                                                             }
  31. { *Functions CSinR, CCosR are much faster than standard functions Sin and Cos }
  32. {    on systems with 80387 and higher. Function CSinCosR calculates both sine }
  33. {    and cosine approx. twice as fast as CSinR and CSosR (on 80387).          }
  34. { *PasCmplx doesn't initiate any exceptions. In case of wrong arguments (for  }
  35. {    example, division by zero) special 80x87 values "NAN" (not a number) or  }
  36. {    "+INF", "-INF" (infinity) are returned. Use CCheck, CCheckR functions to }
  37. {    check quickly complex and real values. Use CTest, CTestR to obtain       }
  38. {    detailed information.                                                    }
  39. { *See PASCMPLX.ASM for details, CMPLXTES.PAS, PASFFT.PAS for examples.       }
  40.  
  41. unit PasCmplx;
  42.  
  43. {$N+}
  44. {$G+}
  45.  
  46. interface
  47.  
  48. type
  49.   Complex = Double;
  50.  
  51. var
  52.   C1: Complex; {complex 1}
  53.   Cj: Complex; {complex j ... or, if it is more convenient, ...}
  54.   Ci: Complex absolute Cj; {complex i}
  55.  
  56. const
  57. {80x87 register state codes reported by CTest and CTestR}
  58.   C87ZerM = 0;  {- 0}
  59.   C87ZerP = 1;  {+ 0}
  60.   C87NorM = 2;  {normalized < 0}
  61.   C87NorP = 3;  {normalized > 0}
  62.   C87Ok   = 3;  {all values > 3 indicate error}
  63.   C87InfM = 4;  {- infinity}
  64.   C87InfP = 5;  {+ infinity}
  65.   C87UnnM = 6;  {- unnormalized}
  66.   C87UnnP = 7;  {+ unnormalized}
  67.   C87DenM = 8;  {- denormalized}
  68.   C87DenP = 9;  {+ denormalized}
  69.   C87NanM = 10; {- not-a-number}
  70.   C87NanP = 11; {+ not-a-number}
  71.   C87Empt = 12; {empty}
  72.  
  73. function CTest87: Integer;
  74. {checks numeric coprocessor}
  75. {returns 80x87 flag: 0=none, 1=8087, 2=80287, 3=80387 and higher}
  76.  
  77. function CInit: Integer;
  78. {initializes complex math unit}
  79. {returns zero if Ok, non-zero else}
  80.  
  81. function Cmplx(A, B: Double): Complex;
  82. {makes complex from a and b}
  83. {returns a + i * b}
  84.  
  85. function CReal(Z: Complex): Double;
  86. {real part from z = a + i * b}
  87. {returns a}
  88.  
  89. function CImag(Z: Complex): Double;
  90. {imaginary part from z = a + i * b}
  91. {returns b}
  92.  
  93. function Conjug(Z: Complex): Complex;
  94. {conjugate complex for z = a + i * b}
  95. {returns a - i * b}
  96.  
  97. function CAdd(Z, P: Complex): Complex;
  98. {adds z = a + i * b and p = c + i * d}
  99. {returns z + p}
  100.  
  101. function CSub(Z, P: Complex): Complex;
  102. {subtracts p = c + i * d from z = a + i * b}
  103. {returns z - p}
  104.  
  105. function CMul(Z, P: Complex): Complex;
  106. {multiplies z = a + i * b and p = c + i * d}
  107. {returns z * p}
  108.  
  109. function CDiv(Z, P: Complex): Complex;
  110. {divides z = a + i * b by p = c + i * d}
  111. {returns z / p}
  112.  
  113. function C1Z(Z: Complex): Complex;
  114. {divides 1 by z = a + i * b}
  115. {returns 1 / z}
  116.  
  117. function CAbs(Z: Complex): Double;
  118. {absolute value of complex z = a + i * b}
  119. {returns abs(z) = a^2 + b^2}
  120.  
  121. function CArg(Z: Complex): Double;
  122. {argument of complex z = a + i * b}
  123. {returns arg(z)}
  124. {NOTE: in common case arg(z) <> arctan(b/a) !}
  125.  
  126. function CExp(Z: Complex): Complex;
  127. {exponential of complex z}
  128. {returns e^z = e^a * (cos(b) + i * sin(b))}
  129.  
  130. function CLn(Z: Complex): Complex;
  131. {natural logarithm of complex z}
  132. {returns ln(z) = ln(abs(z)) + i * arg(z)}
  133. {NOTE: in common case ln(e^z) <> z !}
  134.  
  135. function CPow(Z, P: Complex): Complex;
  136. {complex z in complex power p}
  137. {returns z^p = e^(p * ln(z))}
  138.  
  139. function CRPow(Z: Complex; R: Double): Complex;
  140. {complex z in real power r; works faster than CPow}
  141. {returns z^r = abs(z)^r * (cos(r*arg(z)) + i * sin(r*arg(z)))}
  142.  
  143. function CIPow(Z: Complex; N: Integer): Complex;
  144. {complex z in integer power n; works faster than CRPow}
  145. {returns z^n}
  146.  
  147. function CSinR(R: Double): Double;
  148. {sine of real r; on 80387 uses special instruction}
  149. {returns sin(r)}
  150.  
  151. function CCosR(R: Double): Double;
  152. {sine of real r; on 80387 uses special instruction}
  153. {returns cos(r)}
  154.  
  155. procedure CSinCosR(R: Double; var S, C: Double);
  156. {sine and cosine of real r; on 80387 uses special instruction}
  157. {s := sin(r); c := cos(r)}
  158.  
  159. function CTest(Z: Complex): Word;
  160. {tests complex z}
  161. {returns state of real part in low byte, state of imag. part in high byte}
  162. {the state is one of 80x87 register state flags above}
  163.  
  164. function CTestR(R: Double): Word;
  165. {tests real r}
  166. {returns state of real r in low byte, high byte = 0}
  167. {the state is one of 80x87 register state flags above}
  168.  
  169. function CCheck(Z: Complex): Word;
  170. {checks quickly complex z}
  171. {returns nonzero if real or imag. part invalid (not a zero and
  172.   not a normalized number), zero if both are Ok}
  173.  
  174. function CCheckR(R: Double): Word;
  175. {checks quickly real r}
  176. {returns nonzero if real r invalid (not a zero and not a normalized
  177.   number), zero if it is Ok}
  178.  
  179.  
  180. implementation
  181.  
  182. {$L PASCMPLX}
  183.  
  184. function CTest87; external;
  185. function CInit; external;
  186. function Cmplx; external;
  187. function CReal; external;
  188. function CImag; external;
  189. function Conjug; external;
  190. function CAdd; external;
  191. function CSub; external;
  192. function CMul; external;
  193. function CDiv; external;
  194. function C1Z; external;
  195. function CAbs; external;
  196. function CArg; external;
  197. function CExp; external;
  198. function CLn; external;
  199. function CPow; external;
  200. function CRPow; external;
  201. function CIPow; external;
  202. function CSinR; external;
  203. function CCosR; external;
  204. procedure CSinCosR; external;
  205. function CTest; external;
  206. function CTestR; external;
  207. function CCheck; external;
  208. function CCheckR; external;
  209.  
  210.  
  211. {The following functions are used internally on 80287 systems}
  212. {I'm sorry I was too lazy to write my own Sin/Cos for 80287;}
  213. {if you have your own ones place them here!}
  214.  
  215. function Sin(D: Double): Double;
  216. begin
  217.   Sin := System.Sin(D);
  218. end;
  219.  
  220. function Cos(D: Double): Double;
  221. begin
  222.   Cos := System.Cos(D);
  223. end;
  224.  
  225. begin
  226.   CInit;
  227. end.